Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / MeshChatX.git / files / tests / backend / test_lxmf_send_delivery_oracle.py

Displaying Raw • Download


tests/backend/test_lxmf_send_delivery_oracle.py dev (4e4ef052) Text, 14.66 KB

T8b949e# SPDX-License-Identifier: 0BSD
T8b949e"""Oracles for LXMF outbound send, delivery proofs, and auto-resend cascades.

Guarantee: missing RNS delivery proofs leave opportunistic/direct messages in
SENT (not DELIVERED). Progress polling must not treat that as terminal. Auto
resend only claims failed rows and emits a new hash. Same-content guards do not
treat a failed-only lineage as recent success.

These tests document the no-receipt double-send cascade:
LXMF retries the same hash until MAX_DELIVERY_ATTEMPTS, then MeshChat may
auto-resend a new hash when a peer announces or a path/ping succeeds.
"""

Tff7b72from T7ee787__future__ Tff7b72import Te6edf3annotations

Tff7b72import T7ee787asyncio
Tff7b72import T7ee787time
Tff7b72import T7ee787types
Tff7b72from T7ee787types Tff7b72import Te6edf3SimpleNamespace
Tff7b72from T7ee787unittestT7ee787.T7ee787mock Tff7b72import Te6edf3AsyncMockTb4b4b4, Te6edf3MagicMockTb4b4b4, Te6edf3patch

Tff7b72import T7ee787LXMF
Tff7b72import T7ee787pytest
Tff7b72from T7ee787hypothesis Tff7b72import Te6edf3givenTb4b4b4, Te6edf3settings
Tff7b72from T7ee787hypothesis Tff7b72import Te6edf3strategies Tff7b72as Te6edf3st

Tff7b72from T7ee787meshchatxT7ee787.T7ee787meshchat Tff7b72import Te6edf3ReticulumMeshChat
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backend Tff7b72import Te6edf3auto_resend_guard Tff7b72as Te6edf3guard
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787database Tff7b72import Te6edf3Database
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787databaseT7ee787.T7ee787provider Tff7b72import Te6edf3DatabaseProvider
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787databaseT7ee787.T7ee787schema Tff7b72import Te6edf3DatabaseSchema
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787lxmf_utils Tff7b72import Te6edf3is_lxmf_outbound_progress_terminal


Tff7b72def Td2a8ff_msgTb4b4b4(Tff7b72*Tff7b72*Te6edf3attrsTb4b4b4)Tb4b4b4:
Te6edf3defaults Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4: Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffOUTBOUNDTb4b4b4,
Ta5d6ff"Ta5d6ffmethodTa5d6ff"Tb4b4b4: Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDIRECTTb4b4b4,
Ta5d6ff"Ta5d6fftry_propagation_on_failTa5d6ff"Tb4b4b4: Tff7b72FalseTb4b4b4,
Tb4b4b4}
Te6edf3defaultsTff7b72.Td2a8ffupdateTb4b4b4(Te6edf3attrsTb4b4b4)
Tff7b72return Te6edf3SimpleNamespaceTb4b4b4(Tff7b72*Tff7b72*Te6edf3defaultsTb4b4b4)


Tf0883e@pytestTff7b72.Td2a8fffixture
Tff7b72def Td2a8ffdbTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3path Tff7b72= Tffa657strTb4b4b4(Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffsend_delivery_oracle.dbTa5d6ff"Tb4b4b4)
Te6edf3provider Tff7b72= Te6edf3DatabaseProviderTb4b4b4(Te6edf3pathTb4b4b4)
Te6edf3DatabaseSchemaTb4b4b4(Te6edf3providerTb4b4b4)Tff7b72.Td2a8ffinitializeTb4b4b4(Tb4b4b4)
Te6edf3database Tff7b72= Te6edf3DatabaseTb4b4b4(Te6edf3pathTb4b4b4)
Tff7b72yield Te6edf3database
Te6edf3databaseTff7b72.Td2a8ffclose_allTb4b4b4(Tb4b4b4)
Te6edf3providerTff7b72.Td2a8ffclose_allTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8ff_insert_rowTb4b4b4(
Te6edf3dbTb4b4b4,
Tff7b72*Tb4b4b4,
Te6edf3msg_hashTb4b4b4,
Te6edf3peerTb4b4b4,
Te6edf3contentTb4b4b4,
Te6edf3stateTb4b4b4,
Te6edf3fieldsTff7b72=Ta5d6ff"Tffd700{}Ta5d6ff"Tb4b4b4,
Te6edf3delivery_attemptsTff7b72=T79c0ff0Tb4b4b4,
Te6edf3tsTff7b72=Tff7b72NoneTb4b4b4,
Te6edf3next_atTff7b72=Tff7b72NoneTb4b4b4,
Tb4b4b4)Tb4b4b4:
Te6edf3now Tff7b72= Te6edf3ts Tff7b72if Te6edf3ts Tff7b72is Tff7b72not Tff7b72None Tff7b72else Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Te6edf3dbTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffupsert_lxmf_messageTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6ffhashTa5d6ff"Tb4b4b4: Te6edf3msg_hashTb4b4b4,
Ta5d6ff"Ta5d6ffsource_hashTa5d6ff"Tb4b4b4: Te6edf3peerTb4b4b4,
Ta5d6ff"Ta5d6ffdestination_hashTa5d6ff"Tb4b4b4: Te6edf3peerTb4b4b4,
Ta5d6ff"Ta5d6ffpeer_hashTa5d6ff"Tb4b4b4: Te6edf3peerTb4b4b4,
Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4: Te6edf3stateTb4b4b4,
Ta5d6ff"Ta5d6ffprogressTa5d6ff"Tb4b4b4: T79c0ff1 Tff7b72if Te6edf3state Tff7b72== Ta5d6ff"Ta5d6ffdeliveredTa5d6ff" Tff7b72else T79c0ff0Tb4b4b4,
Ta5d6ff"Ta5d6ffis_incomingTa5d6ff"Tb4b4b4: T79c0ff0Tb4b4b4,
Ta5d6ff"Ta5d6ffmethodTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffopportunisticTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdelivery_attemptsTa5d6ff"Tb4b4b4: Te6edf3delivery_attemptsTb4b4b4,
Ta5d6ff"Ta5d6ffnext_delivery_attempt_atTa5d6ff"Tb4b4b4: Te6edf3next_atTb4b4b4,
Ta5d6ff"Ta5d6fftitleTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffcontentTa5d6ff"Tb4b4b4: Te6edf3contentTb4b4b4,
Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4: Te6edf3fieldsTb4b4b4,
Ta5d6ff"Ta5d6ffrssiTa5d6ff"Tb4b4b4: Tff7b72NoneTb4b4b4,
Ta5d6ff"Ta5d6ffsnrTa5d6ff"Tb4b4b4: Tff7b72NoneTb4b4b4,
Ta5d6ff"Ta5d6ffqualityTa5d6ff"Tb4b4b4: Tff7b72NoneTb4b4b4,
Ta5d6ff"Ta5d6ffis_spamTa5d6ff"Tb4b4b4: T79c0ff0Tb4b4b4,
Ta5d6ff"Ta5d6ffreply_to_hashTa5d6ff"Tb4b4b4: Tff7b72NoneTb4b4b4,
Ta5d6ff"Ta5d6ffattachments_strippedTa5d6ff"Tb4b4b4: T79c0ff0Tb4b4b4,
Ta5d6ff"Ta5d6fftimestampTa5d6ff"Tb4b4b4: Te6edf3nowTb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)


Tff7b72def Td2a8ff_bind_resend_appTb4b4b4(Te6edf3dbTb4b4b4)Tb4b4b4:
Te6edf3app Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3appTff7b72.Td2a8ff_auto_resend_coordinator Tff7b72= Te6edf3guardTff7b72.Td2a8ffAutoResendCoordinatorTb4b4b4(Tb4b4b4)
Te6edf3appTff7b72.Td2a8ffwebsocket_broadcast Tff7b72= Te6edf3AsyncMockTb4b4b4(Tb4b4b4)
Te6edf3appTff7b72.Td2a8ffsend_message Tff7b72= Te6edf3AsyncMockTb4b4b4(Tb4b4b4)
Te6edf3appTff7b72.Td2a8ffresend_failed_messages_for_destination Tff7b72= Te6edf3typesTff7b72.Td2a8ffMethodTypeTb4b4b4(
Te6edf3ReticulumMeshChatTff7b72.Td2a8ffresend_failed_messages_for_destinationTb4b4b4,
Te6edf3appTb4b4b4,
Tb4b4b4)
Te6edf3ctx Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3ctxTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTff7b72.Td2a8ffreturn_value Tff7b72= Ta5d6ff"Ta5d6ffaaTa5d6ff" Tff7b72* T79c0ff16
Te6edf3ctxTff7b72.Td2a8ffdatabase Tff7b72= Te6edf3db
Te6edf3ctxTff7b72.Td2a8ffconfigTff7b72.Td2a8ffallow_auto_resending_failed_messages_with_attachmentsTff7b72.Td2a8ffgetTff7b72.Td2a8ffreturn_value Tff7b72= Tff7b72True
Tff7b72return Te6edf3appTb4b4b4, Te6edf3ctx


Tff7b72def Td2a8fftest_oracle_lxmf_sent_is_not_delivered_without_proofTb4b4b4(Tb4b4b4)Tb4b4b4:
T8b949e"""Independent LXMF contract: SENT != DELIVERED. Proofs flip to DELIVERED."""
Tff7b72assert Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSENT Tff7b72!= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDELIVERED
Tff7b72assert Te6edf3LXMFTff7b72.Td2a8ffLXMRouterTff7b72.Td2a8ffMAX_DELIVERY_ATTEMPTS Tff7b72>Tff7b72= T79c0ff1
Tff7b72assert Te6edf3LXMFTff7b72.Td2a8ffLXMRouterTff7b72.Td2a8ffDELIVERY_RETRY_WAIT Tff7b72> T79c0ff0


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffparametrizeTb4b4b4(
Tb4b4b4(Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffmethodTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6fftry_propTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffexpectedTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4[
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSENTTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffOPPORTUNISTICTb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSENTTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDIRECTTb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffOUTBOUNDTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDIRECTTb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSENDINGTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDIRECTTb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSENTTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffPROPAGATEDTb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72TrueTb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDELIVEREDTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffOPPORTUNISTICTb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72TrueTb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDELIVEREDTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffPROPAGATEDTb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72TrueTb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffFAILEDTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDIRECTTb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72TrueTb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffFAILEDTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDIRECTTb4b4b4, Tff7b72TrueTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffCANCELLEDTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDIRECTTb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72TrueTb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffREJECTEDTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDIRECTTb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72TrueTb4b4b4)Tb4b4b4,
Tb4b4b4]Tb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8fftest_oracle_progress_terminal_matrixTb4b4b4(Te6edf3stateTb4b4b4, Te6edf3methodTb4b4b4, Te6edf3try_propTb4b4b4, Te6edf3expectedTb4b4b4)Tb4b4b4:
Te6edf3msg Tff7b72= Te6edf3_msgTb4b4b4(Te6edf3stateTff7b72=Te6edf3stateTb4b4b4, Te6edf3methodTff7b72=Te6edf3methodTb4b4b4, Te6edf3try_propagation_on_failTff7b72=Te6edf3try_propTb4b4b4)
Tff7b72assert Te6edf3is_lxmf_outbound_progress_terminalTb4b4b4(Te6edf3msgTb4b4b4) Tff7b72is Te6edf3expected


Tf0883e@givenTb4b4b4(
Te6edf3methodTff7b72=Te6edf3stTff7b72.Td2a8ffsampled_fromTb4b4b4(
Tb4b4b4[
Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffOPPORTUNISTICTb4b4b4,
Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDIRECTTb4b4b4,
Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffPAPERTb4b4b4,
Tb4b4b4]
Tb4b4b4)
Tb4b4b4)
Tf0883e@settingsTb4b4b4(Te6edf3max_examplesTff7b72=T79c0ff24Tb4b4b4, Te6edf3deadlineTff7b72=Tff7b72NoneTb4b4b4)
Tff7b72def Td2a8fftest_oracle_sent_without_propagated_never_terminalTb4b4b4(Te6edf3methodTb4b4b4)Tb4b4b4:
T8b949e"""No-receipt peers leave opportunistic/direct at SENT. Must keep polling."""
Tff7b72assert Tff7b72not Te6edf3is_lxmf_outbound_progress_terminalTb4b4b4(
Te6edf3_msgTb4b4b4(Te6edf3stateTff7b72=Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSENTTb4b4b4, Te6edf3methodTff7b72=Te6edf3methodTb4b4b4)
Tb4b4b4)


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_oracle_progress_loop_keeps_polling_opportunistic_sentTb4b4b4(Te6edf3dbTb4b4b4)Tb4b4b4:
Te6edf3app Tff7b72= Te6edf3ReticulumMeshChatTff7b72.Td2a8ff__new__Tb4b4b4(Te6edf3ReticulumMeshChatTb4b4b4)
Te6edf3appTff7b72.Td2a8ffcurrent_context Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3appTff7b72.Td2a8ffcurrent_contextTff7b72.Td2a8ffdatabase Tff7b72= Te6edf3db
Te6edf3appTff7b72.Td2a8ffreticulum Tff7b72= Tff7b72None
Te6edf3appTff7b72.Td2a8ffwebsocket_broadcast Tff7b72= Te6edf3AsyncMockTb4b4b4(Tb4b4b4)
Te6edf3appTff7b72.Td2a8ff_maybe_store_path_at_send_for_lxmf Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3appTff7b72.Td2a8ff_merge_stored_path_fields_from_db Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)

Te6edf3peer Tff7b72= Ta5d6ff"Ta5d6ffbTa5d6ff" Tff7b72* T79c0ff32
Te6edf3msg_hash Tff7b72= Ta5d6ff"Ta5d6ffcTa5d6ff" Tff7b72* T79c0ff32
Te6edf3_insert_rowTb4b4b4(Te6edf3dbTb4b4b4, Te6edf3msg_hashTff7b72=Te6edf3msg_hashTb4b4b4, Te6edf3peerTff7b72=Te6edf3peerTb4b4b4, Te6edf3contentTff7b72=Ta5d6ff"Ta5d6ffhiTa5d6ff"Tb4b4b4, Te6edf3stateTff7b72=Ta5d6ff"Ta5d6ffoutboundTa5d6ff"Tb4b4b4)

Te6edf3mock_msg Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3mock_msgTff7b72.Td2a8ffhash Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3msg_hashTb4b4b4)
Te6edf3mock_msgTff7b72.Td2a8ffprogress Tff7b72= T79c0ff0.0
Te6edf3mock_msgTff7b72.Td2a8ffdelivery_attempts Tff7b72= T79c0ff1
Te6edf3mock_msgTff7b72.Td2a8ffstate Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSENT
Te6edf3mock_msgTff7b72.Td2a8ffmethod Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffOPPORTUNISTIC
Te6edf3mock_msgTff7b72.Td2a8fftry_propagation_on_fail Tff7b72= Tff7b72False
Te6edf3mock_msgTff7b72.Td2a8ffnext_delivery_attempt Tff7b72= Tff7b72None
T8b949e# Avoid MagicMock auto-attrs leaking into SQLite binds.
Tffa657typeTb4b4b4(Te6edf3mock_msgTb4b4b4)Tff7b72.Td2a8ffrssi Tff7b72= Tffa657propertyTb4b4b4(Tff7b72lambda Tff7b72selfTb4b4b4: Tff7b72NoneTb4b4b4)
Tffa657typeTb4b4b4(Te6edf3mock_msgTb4b4b4)Tff7b72.Td2a8ffsnr Tff7b72= Tffa657propertyTb4b4b4(Tff7b72lambda Tff7b72selfTb4b4b4: Tff7b72NoneTb4b4b4)
Tffa657typeTb4b4b4(Te6edf3mock_msgTb4b4b4)Tff7b72.Td2a8ffq Tff7b72= Tffa657propertyTb4b4b4(Tff7b72lambda Tff7b72selfTb4b4b4: Tff7b72NoneTb4b4b4)

Te6edf3sleeps Tff7b72= T79c0ff0

Tff7b72async Tff7b72def Td2a8ffcount_sleepTb4b4b4(Te6edf3_durationTb4b4b4)Tb4b4b4:
Tff7b72nonlocal Te6edf3sleeps
Te6edf3sleeps Tff7b72+Tff7b72= T79c0ff1
Tff7b72if Te6edf3sleeps Tff7b72>Tff7b72= T79c0ff2Tb4b4b4:
Te6edf3mock_msgTff7b72.Td2a8ffstate Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffFAILED

Tff7b72with Tb4b4b4(
Te6edf3patchTb4b4b4(
Ta5d6ff"Ta5d6ffmeshchatx.meshchat.convert_lxmf_message_to_dictTa5d6ff"Tb4b4b4,
Te6edf3return_valueTff7b72=Tb4b4b4{Ta5d6ff"Ta5d6ffhashTa5d6ff"Tb4b4b4: Te6edf3msg_hashTb4b4b4, Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffsentTa5d6ff"Tb4b4b4}Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffasyncio.sleepTa5d6ff"Tb4b4b4, Te6edf3side_effectTff7b72=Te6edf3count_sleepTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4:
Tff7b72await Te6edf3ReticulumMeshChatTff7b72.Td2a8ffhandle_lxmf_message_progressTb4b4b4(
Te6edf3appTb4b4b4,
Te6edf3mock_msgTb4b4b4,
Te6edf3contextTff7b72=Te6edf3appTff7b72.Td2a8ffcurrent_contextTb4b4b4,
Tb4b4b4)

Tff7b72assert Te6edf3sleeps Tff7b72>Tff7b72= T79c0ff2
Te6edf3row Tff7b72= Te6edf3dbTff7b72.Td2a8ffproviderTff7b72.Td2a8fffetchoneTb4b4b4(
Ta5d6ff"Ta5d6ffSELECT state FROM lxmf_messages WHERE hash = ?Ta5d6ff"Tb4b4b4,
Tb4b4b4(Te6edf3msg_hashTb4b4b4,Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72assert Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6fffailedTa5d6ff"


Tff7b72def Td2a8fftest_oracle_claim_refuses_non_failed_statesTb4b4b4(Te6edf3dbTb4b4b4)Tb4b4b4:
Te6edf3peer Tff7b72= Ta5d6ff"Ta5d6ffdTa5d6ff" Tff7b72* T79c0ff32
Te6edf3now Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72for Te6edf3stateTb4b4b4, Te6edf3msg_hash Tff7b72in Tb4b4b4(
Tb4b4b4(Ta5d6ff"Ta5d6ffsentTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff1Ta5d6ff" Tff7b72* T79c0ff32Tb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6ffoutboundTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff2Ta5d6ff" Tff7b72* T79c0ff32Tb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6ffdeliveredTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff3Ta5d6ff" Tff7b72* T79c0ff32Tb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6ffsendingTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff4Ta5d6ff" Tff7b72* T79c0ff32Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4:
Te6edf3_insert_rowTb4b4b4(
Te6edf3dbTb4b4b4,
Te6edf3msg_hashTff7b72=Te6edf3msg_hashTb4b4b4,
Te6edf3peerTff7b72=Te6edf3peerTb4b4b4,
Te6edf3contentTff7b72=Ta5d6ff"Ta5d6ffbodyTa5d6ff"Tb4b4b4,
Te6edf3stateTff7b72=Te6edf3stateTb4b4b4,
Te6edf3delivery_attemptsTff7b72=T79c0ff3Tb4b4b4,
Tb4b4b4)
Tff7b72assert Tff7b72not Te6edf3dbTff7b72.Td2a8ffmessagesTff7b72.Td2a8fftry_claim_failed_message_for_auto_resendTb4b4b4(
Te6edf3msg_hashTb4b4b4,
Te6edf3cooldown_untilTff7b72=Te6edf3now Tff7b72+ T79c0ff120Tb4b4b4,
Te6edf3nowTff7b72=Te6edf3nowTb4b4b4,
Tb4b4b4)


Tff7b72def Td2a8fftest_oracle_failed_only_lineage_does_not_count_as_recent_successTb4b4b4(Te6edf3dbTb4b4b4)Tb4b4b4:
T8b949e"""After no-proof FAILED, only the failed row remains. Auto-resend may fire."""
Te6edf3peer Tff7b72= Ta5d6ff"Ta5d6ffeTa5d6ff" Tff7b72* T79c0ff32
Te6edf3now Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Te6edf3_insert_rowTb4b4b4(
Te6edf3dbTb4b4b4,
Te6edf3msg_hashTff7b72=Ta5d6ff"Ta5d6ff5Ta5d6ff" Tff7b72* T79c0ff32Tb4b4b4,
Te6edf3peerTff7b72=Te6edf3peerTb4b4b4,
Te6edf3contentTff7b72=Ta5d6ff"Ta5d6ffsame bodyTa5d6ff"Tb4b4b4,
Te6edf3stateTff7b72=Ta5d6ff"Ta5d6fffailedTa5d6ff"Tb4b4b4,
Te6edf3delivery_attemptsTff7b72=Te6edf3LXMFTff7b72.Td2a8ffLXMRouterTff7b72.Td2a8ffMAX_DELIVERY_ATTEMPTSTb4b4b4,
Te6edf3tsTff7b72=Te6edf3now Tff7b72- T79c0ff10Tb4b4b4,
Tb4b4b4)
Tff7b72assert Tff7b72not Te6edf3dbTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffhas_recent_outbound_with_contentTb4b4b4(
Te6edf3peerTb4b4b4,
Ta5d6ff"Ta5d6ffsame bodyTa5d6ff"Tb4b4b4,
Te6edf3within_secondsTff7b72=T79c0ff300Tb4b4b4,
Te6edf3nowTff7b72=Te6edf3nowTb4b4b4,
Tb4b4b4)


Tff7b72def Td2a8fftest_oracle_in_flight_sent_blocks_same_content_resendTb4b4b4(Te6edf3dbTb4b4b4)Tb4b4b4:
T8b949e"""While LXMF still holds SENT (retrying proofs), do not treat as free to resend."""
Te6edf3peer Tff7b72= Ta5d6ff"Ta5d6fffTa5d6ff" Tff7b72* T79c0ff32
Te6edf3now Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Te6edf3_insert_rowTb4b4b4(
Te6edf3dbTb4b4b4,
Te6edf3msg_hashTff7b72=Ta5d6ff"Ta5d6ff6Ta5d6ff" Tff7b72* T79c0ff32Tb4b4b4,
Te6edf3peerTff7b72=Te6edf3peerTb4b4b4,
Te6edf3contentTff7b72=Ta5d6ff"Ta5d6ffin flightTa5d6ff"Tb4b4b4,
Te6edf3stateTff7b72=Ta5d6ff"Ta5d6ffsentTa5d6ff"Tb4b4b4,
Te6edf3delivery_attemptsTff7b72=T79c0ff2Tb4b4b4,
Te6edf3tsTff7b72=Te6edf3now Tff7b72- T79c0ff5Tb4b4b4,
Tb4b4b4)
Tff7b72assert Te6edf3dbTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffhas_recent_outbound_with_contentTb4b4b4(
Te6edf3peerTb4b4b4,
Ta5d6ff"Ta5d6ffin flightTa5d6ff"Tb4b4b4,
Te6edf3within_secondsTff7b72=T79c0ff300Tb4b4b4,
Te6edf3nowTff7b72=Te6edf3nowTb4b4b4,
Tb4b4b4)


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_oracle_auto_resend_skips_sent_rows_and_only_claims_failedTb4b4b4(Te6edf3dbTb4b4b4)Tb4b4b4:
Te6edf3peer Tff7b72= Ta5d6ff"Ta5d6ff7Ta5d6ff" Tff7b72* T79c0ff32
Te6edf3_insert_rowTb4b4b4(Te6edf3dbTb4b4b4, Te6edf3msg_hashTff7b72=Ta5d6ff"Ta5d6ff8Ta5d6ff" Tff7b72* T79c0ff32Tb4b4b4, Te6edf3peerTff7b72=Te6edf3peerTb4b4b4, Te6edf3contentTff7b72=Ta5d6ff"Ta5d6ffaliveTa5d6ff"Tb4b4b4, Te6edf3stateTff7b72=Ta5d6ff"Ta5d6ffsentTa5d6ff"Tb4b4b4)
Te6edf3_insert_rowTb4b4b4(Te6edf3dbTb4b4b4, Te6edf3msg_hashTff7b72=Ta5d6ff"Ta5d6ff9Ta5d6ff" Tff7b72* T79c0ff32Tb4b4b4, Te6edf3peerTff7b72=Te6edf3peerTb4b4b4, Te6edf3contentTff7b72=Ta5d6ff"Ta5d6ffdeadTa5d6ff"Tb4b4b4, Te6edf3stateTff7b72=Ta5d6ff"Ta5d6fffailedTa5d6ff"Tb4b4b4)
Te6edf3appTb4b4b4, Te6edf3ctx Tff7b72= Te6edf3_bind_resend_appTb4b4b4(Te6edf3dbTb4b4b4)

Te6edf3new_hash Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Ta5d6ff"Ta5d6ffaTa5d6ff" Tff7b72* T79c0ff32Tb4b4b4)

Tff7b72async Tff7b72def Td2a8ffsend_okTb4b4b4(Tff7b72*Te6edf3argsTb4b4b4, Tff7b72*Tff7b72*Te6edf3kwargsTb4b4b4)Tb4b4b4:
Te6edf3m Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3mTff7b72.Td2a8ffhash Tff7b72= Te6edf3new_hash
Te6edf3_insert_rowTb4b4b4(
Te6edf3dbTb4b4b4,
Te6edf3msg_hashTff7b72=Te6edf3new_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3peerTff7b72=Te6edf3peerTb4b4b4,
Te6edf3contentTff7b72=Ta5d6ff"Ta5d6ffdeadTa5d6ff"Tb4b4b4,
Te6edf3stateTff7b72=Ta5d6ff"Ta5d6ffoutboundTa5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3m

Te6edf3appTff7b72.Td2a8ffsend_messageTff7b72.Td2a8ffside_effect Tff7b72= Te6edf3send_ok
Tff7b72await Te6edf3appTff7b72.Td2a8ffresend_failed_messages_for_destinationTb4b4b4(Te6edf3peerTb4b4b4, Te6edf3contextTff7b72=Te6edf3ctxTb4b4b4)
Tff7b72assert Te6edf3appTff7b72.Td2a8ffsend_messageTff7b72.Td2a8ffawait_count Tff7b72== T79c0ff1
Tff7b72assert Tb4b4b4(
Te6edf3dbTff7b72.Td2a8ffproviderTff7b72.Td2a8fffetchoneTb4b4b4(
Ta5d6ff"Ta5d6ffSELECT state FROM lxmf_messages WHERE hash = ?Ta5d6ff"Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6ff8Ta5d6ff" Tff7b72* T79c0ff32Tb4b4b4,Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4[Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4]
Tff7b72== Ta5d6ff"Ta5d6ffsentTa5d6ff"
Tb4b4b4)
Tff7b72assert Tb4b4b4(
Te6edf3dbTff7b72.Td2a8ffproviderTff7b72.Td2a8fffetchoneTb4b4b4(
Ta5d6ff"Ta5d6ffSELECT 1 FROM lxmf_messages WHERE hash = ?Ta5d6ff"Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6ff9Ta5d6ff" Tff7b72* T79c0ff32Tb4b4b4,Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72is Tff7b72None
Tb4b4b4)


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_oracle_auto_resend_emits_new_hash_not_same_hashTb4b4b4(Te6edf3dbTb4b4b4)Tb4b4b4:
Te6edf3peer Tff7b72= Ta5d6ff"Ta5d6ffbTa5d6ff" Tff7b72* T79c0ff32
Te6edf3old_hash Tff7b72= Ta5d6ff"Ta5d6ffcTa5d6ff" Tff7b72* T79c0ff32
Te6edf3new_hash Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Ta5d6ff"Ta5d6ffdTa5d6ff" Tff7b72* T79c0ff32Tb4b4b4)
Te6edf3_insert_rowTb4b4b4(Te6edf3dbTb4b4b4, Te6edf3msg_hashTff7b72=Te6edf3old_hashTb4b4b4, Te6edf3peerTff7b72=Te6edf3peerTb4b4b4, Te6edf3contentTff7b72=Ta5d6ff"Ta5d6ffretryTa5d6ff"Tb4b4b4, Te6edf3stateTff7b72=Ta5d6ff"Ta5d6fffailedTa5d6ff"Tb4b4b4)
Te6edf3appTb4b4b4, Te6edf3ctx Tff7b72= Te6edf3_bind_resend_appTb4b4b4(Te6edf3dbTb4b4b4)

Tff7b72async Tff7b72def Td2a8ffsend_okTb4b4b4(Tff7b72*Te6edf3argsTb4b4b4, Tff7b72*Tff7b72*Te6edf3kwargsTb4b4b4)Tb4b4b4:
Te6edf3m Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3mTff7b72.Td2a8ffhash Tff7b72= Te6edf3new_hash
Te6edf3_insert_rowTb4b4b4(
Te6edf3dbTb4b4b4,
Te6edf3msg_hashTff7b72=Te6edf3new_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3peerTff7b72=Te6edf3peerTb4b4b4,
Te6edf3contentTff7b72=Ta5d6ff"Ta5d6ffretryTa5d6ff"Tb4b4b4,
Te6edf3stateTff7b72=Ta5d6ff"Ta5d6ffoutboundTa5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3m

Te6edf3appTff7b72.Td2a8ffsend_messageTff7b72.Td2a8ffside_effect Tff7b72= Te6edf3send_ok
Tff7b72await Te6edf3appTff7b72.Td2a8ffresend_failed_messages_for_destinationTb4b4b4(Te6edf3peerTb4b4b4, Te6edf3contextTff7b72=Te6edf3ctxTb4b4b4)
Tff7b72assert Te6edf3new_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4) Tff7b72!= Te6edf3old_hash
Tff7b72assert Te6edf3appTff7b72.Td2a8ffsend_messageTff7b72.Td2a8ffawait_count Tff7b72== T79c0ff1
Tff7b72assert Tb4b4b4(
Te6edf3guardTff7b72.Td2a8ffread_auto_resend_countTb4b4b4(
Te6edf3dbTff7b72.Td2a8ffproviderTff7b72.Td2a8fffetchoneTb4b4b4(
Ta5d6ff"Ta5d6ffSELECT fields FROM lxmf_messages WHERE hash = ?Ta5d6ff"Tb4b4b4,
Tb4b4b4(Te6edf3new_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4,Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4[Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4]
Tb4b4b4)
Tff7b72== T79c0ff1
Tb4b4b4)


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_oracle_propagation_fallback_clears_packed_and_requeues_same_objectTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3app Tff7b72= Te6edf3ReticulumMeshChatTff7b72.Td2a8ff__new__Tb4b4b4(Te6edf3ReticulumMeshChatTb4b4b4)
Te6edf3ctx Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3ctxTff7b72.Td2a8ffforwarding_manager Tff7b72= Tff7b72None
Te6edf3ctxTff7b72.Td2a8ffmessage_router Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3appTff7b72.Td2a8ffcurrent_context Tff7b72= Te6edf3ctx

Te6edf3original_id Tff7b72= Tffa657objectTb4b4b4(Tb4b4b4)
Te6edf3lxmf_message Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3lxmf_messageTff7b72.Td2a8ff__id Tff7b72= Te6edf3original_id
Te6edf3lxmf_messageTff7b72.Td2a8ffpacked Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6ffstale-packetTa5d6ff"
Te6edf3lxmf_messageTff7b72.Td2a8ffdelivery_attempts Tff7b72= T79c0ff5
Te6edf3lxmf_messageTff7b72.Td2a8ffnext_delivery_attempt Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72+ T79c0ff10
Te6edf3lxmf_messageTff7b72.Td2a8ffsource_hash Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Ta5d6ff"Ta5d6ff11Ta5d6ff" Tff7b72* T79c0ff16Tb4b4b4)
Te6edf3lxmf_messageTff7b72.Td2a8ffmessage_id Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6ffmidTa5d6ff" Tff7b72* T79c0ff5 Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffxxTa5d6ff"

Te6edf3ReticulumMeshChatTff7b72.Td2a8ffsend_failed_message_via_propagation_nodeTb4b4b4(
Te6edf3appTb4b4b4,
Te6edf3lxmf_messageTb4b4b4,
Te6edf3contextTff7b72=Te6edf3ctxTb4b4b4,
Tb4b4b4)

Tff7b72assert Te6edf3lxmf_messageTff7b72.Td2a8ffpacked Tff7b72is Tff7b72None
Tff7b72assert Te6edf3lxmf_messageTff7b72.Td2a8ffdelivery_attempts Tff7b72== T79c0ff0
Tff7b72assert Te6edf3lxmf_messageTff7b72.Td2a8ffdesired_method Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffPROPAGATED
Tff7b72assert Te6edf3lxmf_messageTff7b72.Td2a8fftry_propagation_on_fail Tff7b72is Tff7b72False
Tff7b72assert Tff7b72not Tffa657hasattrTb4b4b4(Te6edf3lxmf_messageTb4b4b4, Ta5d6ff"Ta5d6ffnext_delivery_attemptTa5d6ff"Tb4b4b4)
Te6edf3ctxTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffhandle_outboundTff7b72.Td2a8ffassert_called_once_withTb4b4b4(Te6edf3lxmf_messageTb4b4b4)


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_oracle_concurrent_resend_claims_send_onceTb4b4b4(Te6edf3dbTb4b4b4)Tb4b4b4:
Te6edf3peer Tff7b72= Ta5d6ff"Ta5d6ffeTa5d6ff" Tff7b72* T79c0ff32
Te6edf3old_hash Tff7b72= Ta5d6ff"Ta5d6fffTa5d6ff" Tff7b72* T79c0ff32
Te6edf3_insert_rowTb4b4b4(Te6edf3dbTb4b4b4, Te6edf3msg_hashTff7b72=Te6edf3old_hashTb4b4b4, Te6edf3peerTff7b72=Te6edf3peerTb4b4b4, Te6edf3contentTff7b72=Ta5d6ff"Ta5d6ffraceTa5d6ff"Tb4b4b4, Te6edf3stateTff7b72=Ta5d6ff"Ta5d6fffailedTa5d6ff"Tb4b4b4)
Te6edf3appTb4b4b4, Te6edf3ctx Tff7b72= Te6edf3_bind_resend_appTb4b4b4(Te6edf3dbTb4b4b4)

Tff7b72async Tff7b72def Td2a8ffslow_sendTb4b4b4(Tff7b72*Te6edf3argsTb4b4b4, Tff7b72*Tff7b72*Te6edf3kwargsTb4b4b4)Tb4b4b4:
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.05Tb4b4b4)
Te6edf3m Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3mTff7b72.Td2a8ffhash Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Ta5d6ff"Ta5d6ff1Ta5d6ff" Tff7b72* T79c0ff32Tb4b4b4)
Te6edf3_insert_rowTb4b4b4(
Te6edf3dbTb4b4b4,
Te6edf3msg_hashTff7b72=Te6edf3mTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3peerTff7b72=Te6edf3peerTb4b4b4,
Te6edf3contentTff7b72=Ta5d6ff"Ta5d6ffraceTa5d6ff"Tb4b4b4,
Te6edf3stateTff7b72=Ta5d6ff"Ta5d6ffoutboundTa5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3m

Te6edf3appTff7b72.Td2a8ffsend_messageTff7b72.Td2a8ffside_effect Tff7b72= Te6edf3slow_send
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffgatherTb4b4b4(
Te6edf3appTff7b72.Td2a8ffresend_failed_messages_for_destinationTb4b4b4(Te6edf3peerTb4b4b4, Te6edf3contextTff7b72=Te6edf3ctxTb4b4b4)Tb4b4b4,
Te6edf3appTff7b72.Td2a8ffresend_failed_messages_for_destinationTb4b4b4(Te6edf3peerTb4b4b4, Te6edf3contextTff7b72=Te6edf3ctxTb4b4b4)Tb4b4b4,
Te6edf3appTff7b72.Td2a8ffresend_failed_messages_for_destinationTb4b4b4(Te6edf3peerTb4b4b4, Te6edf3contextTff7b72=Te6edf3ctxTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72assert Te6edf3appTff7b72.Td2a8ffsend_messageTff7b72.Td2a8ffawait_count Tff7b72== T79c0ff1


Tff7b72def Td2a8fftest_oracle_no_receipt_cascade_contract_documentedTb4b4b4(Tb4b4b4)Tb4b4b4:
T8b949e"""Closed contract for peers that never return delivery proofs."""
Tff7b72from T7ee787pathlib Tff7b72import Te6edf3Path

T8b949e# 1) Proof required for DELIVERED
Tff7b72assert Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSENT Tff7b72!= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDELIVERED
T8b949e# 2) Library retries same outbound object
Tff7b72assert Te6edf3LXMFTff7b72.Td2a8ffLXMRouterTff7b72.Td2a8ffMAX_DELIVERY_ATTEMPTS Tff7b72== T79c0ff5
T8b949e# 3) Progress must keep polling SENT opportunistic
Tff7b72assert Tff7b72not Te6edf3is_lxmf_outbound_progress_terminalTb4b4b4(
Te6edf3_msgTb4b4b4(
Te6edf3stateTff7b72=Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSENTTb4b4b4,
Te6edf3methodTff7b72=Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffOPPORTUNISTICTb4b4b4,
Tb4b4b4)
Tb4b4b4)
T8b949e# 4) Only FAILED is auto-resend eligible (claim SQL requires state=failed)
Te6edf3messages_src Tff7b72= Tb4b4b4(
Te6edf3PathTb4b4b4(Tff7b72__file__Tb4b4b4)Tff7b72.Td2a8ffresolveTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffparentsTb4b4b4[T79c0ff2Tb4b4b4]
Tff7b72/ Ta5d6ff"Ta5d6ffmeshchatxTa5d6ff"
Tff7b72/ Ta5d6ff"Ta5d6ffsrcTa5d6ff"
Tff7b72/ Ta5d6ff"Ta5d6ffbackendTa5d6ff"
Tff7b72/ Ta5d6ff"Ta5d6ffdatabaseTa5d6ff"
Tff7b72/ Ta5d6ff"Ta5d6ffmessages.pyTa5d6ff"
Tb4b4b4)Tff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6ffstate = Ta5d6ff'Ta5d6fffailedTa5d6ff'Ta5d6ff" Tff7b72in Te6edf3messages_src
Tff7b72assert Ta5d6ff"Ta5d6fftry_claim_failed_message_for_auto_resendTa5d6ff" Tff7b72in Te6edf3messages_src
T8b949e# 5) Auto-resend budget caps replacement floods
Tff7b72assert Te6edf3guardTff7b72.Td2a8ffMAX_AUTO_RESEND_ATTEMPTS Tff7b72== T79c0ff3
Tff7b72assert Te6edf3guardTff7b72.Td2a8ffAUTO_RESEND_COOLDOWN_SECONDS Tff7b72== T79c0ff120
Tff7b72assert Te6edf3guardTff7b72.Td2a8ffRECENT_SAME_CONTENT_SECONDS Tff7b72== T79c0ff300


Tff7b72def Td2a8fftest_lxmf_send_delivery_oracle_provedTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3pairs Tff7b72= T79c0ff0
Tff7b72for Te6edf3stateTb4b4b4, Te6edf3methodTb4b4b4, Te6edf3expected Tff7b72in Tb4b4b4(
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSENTTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffOPPORTUNISTICTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSENTTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDIRECTTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSENTTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffPROPAGATEDTb4b4b4, Tff7b72TrueTb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDELIVEREDTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDIRECTTb4b4b4, Tff7b72TrueTb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffFAILEDTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDIRECTTb4b4b4, Tff7b72TrueTb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffCANCELLEDTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDIRECTTb4b4b4, Tff7b72TrueTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4:
Tff7b72assert Tb4b4b4(
Te6edf3is_lxmf_outbound_progress_terminalTb4b4b4(Te6edf3_msgTb4b4b4(Te6edf3stateTff7b72=Te6edf3stateTb4b4b4, Te6edf3methodTff7b72=Te6edf3methodTb4b4b4)Tb4b4b4)
Tff7b72is Te6edf3expected
Tb4b4b4)
Te6edf3pairs Tff7b72+Tff7b72= T79c0ff1
Tff7b72assert Te6edf3pairs Tff7b72== T79c0ff6
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffLXMF_SEND_DELIVERY_ORACLE_PROVEDTa5d6ff"Tb4b4b4)


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────